STM32学习心得三十五(上):VS1053实验之RAM测试及正弦测试 |
您所在的位置:网站首页 › stm32输出正弦波 接功放 › STM32学习心得三十五(上):VS1053实验之RAM测试及正弦测试 |
记录一下,方便以后翻阅~ 主要内容: 1) 硬件连接; 2) VS1053简介; 3) 相关实验及其代码解读。 实验功能:程序开启后,系统先进行RAM测试,再进行正弦测试,可以接耳机听到所设的单频声音。备注:音乐播放实验还未深入研究,本章内容不涉及。 硬件连接:如下图所示: 1.2 特点 1) 支持OGG/MP3/WMA/WAV/FLAC(需加载patch)/MIDI/AAC等格式解码; 2) 支持OGG(需加载patch)/IMA ADPCM编码; 3) 支持音量调节、高低音控制和EarSpeaker空间效果; 4) 自带高性能立体声ADC和DAC,音质比VS 1003好很多; 5) 自带耳机驱动器,可驱动30欧负载的耳机; 6) 自带8个GPIO,可用于控制外设/作为I2S接口(外接DAC ); 7) 通过SPI接口控制/传输数据,接口简单; 8) 可通过加载patch,实现新功能添加; 9) 低功耗 。 1.3 接口介绍 VS1053通过SPI接口来接受输入的音频数据流,它可以是一个系统的从机,也可以作为独立的主机。本例程,我们把它当成从机使用。我们通过SPI口向VS1053不停的输入音频数据,它就会自动帮我们解码了,然后从输出通道输出音乐,这时我们接上耳机就能听到所播放的歌曲了。 VS1053通过7根线同MCU连接,如下: VS_RST:VS1053的复位信号线,低电平有效; VS_DREQ:数据请求信号(高电平有效),用来通知主机,VS1053是否可以接收数据; VS_XCS:命令片选(低电平有效); VS_XDCS:数据片选(低电平有效); VS_MISO、VS_MOSI和VS_SCK:SPI信号线。 1.4 VS1053工作模式 VS1053的SPI支持两种工作模式: 1,VS1002有效模式(即新模式); 2,VS1001兼容模式。 这里仅介绍VS1002有效模式(此模式也是VS1053的默认模式)。在新模式下VS1053的SPI信号线功能描述如下表所示: 1.5 VS1053之SCI命令传输介绍 SCI串行总线命令接口包含了一个指令字节、一个地址字节和一个16位的数据字。读写操作可以读写单个寄存器,在SCK的上升沿读出数据位,所以主机必须在下降沿刷新数据。SCI的字节数据总是高位在前低位在后的。第一个字节指令字节,只有2个指令,也就是读和写,读为0X03,写为0X02。 SCI读时序如下图所示: 2. VS1053寄存器介绍 2.1 VS1053的所有的SCI寄存器,如下表: 2.3 BASS寄存器(0X02) 2.4 CLOCKF寄存器(0X03) 2.5 DECODE_TIME寄存器(0X04) 该寄存器是一个存放解码时间的寄存器,以秒钟为单位,我们通过读取该寄存器的值,就可以得到解码时间。不过,它是一个累计时间,在每首歌播放之前,需要把它清空一下,以得到这首歌的准确解码时间。 2.6 HDAT0&HDAT1寄存器(0X08&0X09) 这两个寄存器,是数据流头寄存器,不同的音频文件,读出来的值意义不一样,我们可以通过这两个寄存器来获取音频文件的码率,从而可以计算音频文件的总长度。这两个寄存器的详细介绍,请参考:VS1053的数据手册(VS1053_cn.pdf)。 2.7 VOL寄存器(0X0B) 该寄存器用于控制VS1053的输出音量,该寄存器可以分别控制左右声道的音量,每个声道的控制范围为0~254,每个增量代表0.5db的衰减,所以该值越小,代表音量越大。比如设置为0X0000则音量最大,而设置为0XFEFE则音量最小。 注意:如果设置VOL的值为0XFFFF,将使芯片进入掉电模式! 3 VS1053初始化步骤 1) 复位VS1053 包括硬复位和软复位,让VS1053恢复初始状态,准备解码下一首歌曲。在每首歌曲播放之前都可以执行一次硬件复位和软件复位,以便更好的播放音乐。 2) 配置VS1053的相关寄存器 这里配置的寄存器包括VS1053的模式寄存器(MODE)、时钟寄存器(CLOCKF)、音调寄存器(BASS)、音量寄存器(VOL)等。 3) 发送音频数据 经过以上①、②配置以后,剩下来要做的事情,就是往VS1053里面发送音频数据,只要是VS1053支持的音频格式,直接往里面丢就可以了,VS1053会自动识别,并进行播放。不过,发送数据要在DREQ信号的控制下有序的进行,不能乱发。这个规则很简单:只要DREQ变高,就向VS1053发送32个字节。然后继续等待DREQ变高,直到音频数据发送完。 4. 部分源码讲解 4.1 VS1053低速2.25MHz,高速9MHz。 /******************************************************************************* 函数名称:u8 VS_SPI_ReadWriteByte(u8 data) 函数功能:读写数据,移植用 入口参数:u8 data:要写入的数据 返回参数:u8 读到的数据 解读作者:Aaron ********************************************************************************/ u8 VS_SPI_ReadWriteByte(u8 data) { return SPI1_ReadWriteByte(data); } /* VS1053初始化时,需要低速 */ void VS_SPI_SpeedLow(void) { SPI1_SetSpeed(SPI_BaudRatePrescaler_32); /* 设置低速模式,72/32≈2.25MHz */ } /* VS1053正常工作时,可以高速 */ void VS_SPI_SpeedHigh(void) { SPI1_SetSpeed(SPI_BaudRatePrescaler_8); /* 设置高速模式,72/8=9MHz */ }这么设置的原因如下表(VS1053芯片手册): 5 相关实验代码解读 5.1 vs10xx.c部分代码(我修改了下) /********************************************************************** 函数名称:VS_Init() 函数功能:初始化VS10XX的IO口 入口参数:无 返回参数:无 解读作者:Aaron ***********************************************************************/ void VS_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE); /* 使能PC,PE,PF端口时钟 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* 上拉输入 */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); /* 初始化PC13,对应VS_DREQ(数据请求信号) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 推挽输出 */ GPIO_Init(GPIOE, &GPIO_InitStructure); /* 初始化PE6,对应复位信号线 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 推挽输出 */ GPIO_Init(GPIOF, &GPIO_InitStructure); /* 初始化PF6和PF7,对应VS_XDCS(数据片选)和VS_XCS(命令片选) */ SPI1_Init(); /* 初始化SPI */ } /********************************************************************** 函数名称:VS_Sine_Test() 函数功能:正弦测试 入口参数:无 返回参数:无 解读作者:Aaron ***********************************************************************/ void VS_Sine_Test(void) { VS_HD_Reset(); /* 硬件复位 */ VS_WR_Cmd(0x0b,0X5050); /* 设置音量,值越小声音越大 */ VS_WR_Cmd(SPI_MODE,0x0820); /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */ while(VS_DQ==0); /* 等待DREQ为高 */ printf("mode sin:%x\n",VS_RD_Reg(SPI_MODE)); /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00 其中n = 0x28=0b00101000, 即FS=48000Hz,频率=48000*8/128=3000Hz */ VS_SPI_SpeedLow(); /* 低速模式 */ VS_XDCS=0; /* 选中数据传输 */ VS_SPI_ReadWriteByte(0x53); VS_SPI_ReadWriteByte(0xef); VS_SPI_ReadWriteByte(0x6e); VS_SPI_ReadWriteByte(0x28); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); delay_ms(200); /* 测试经验告诉我,延迟时间不能超过1s */ VS_XDCS=1; /* 退出正弦测试 */ VS_XDCS=0; /* 选中数据传输 */ VS_SPI_ReadWriteByte(0x45); VS_SPI_ReadWriteByte(0x78); VS_SPI_ReadWriteByte(0x69); VS_SPI_ReadWriteByte(0x74); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); delay_ms(100); VS_XDCS=1; /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00其 中n = 0x22=0b001 00010, 即FS=48000Hz,频率=48000*2/128=750Hz */ VS_HD_Reset(); /* 硬件复位 */ VS_WR_Cmd(0x0b,0X5050); /* 设置音量,值越小声音越大 */ VS_WR_Cmd(SPI_MODE,0x0820); /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */ while(VS_DQ==0); /* 等待DREQ为高 */ VS_SPI_SpeedLow(); /* 低速模式 */ VS_XDCS=0; /* 选中数据传输 */ VS_SPI_ReadWriteByte(0x53); VS_SPI_ReadWriteByte(0xef); VS_SPI_ReadWriteByte(0x6e); VS_SPI_ReadWriteByte(0x22); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); delay_ms(400); VS_XDCS=1; /* 退出正弦测试 */ VS_XDCS=0; /* 选中数据传输 */ VS_SPI_ReadWriteByte(0x45); VS_SPI_ReadWriteByte(0x78); VS_SPI_ReadWriteByte(0x69); VS_SPI_ReadWriteByte(0x74); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); delay_ms(100); VS_XDCS=1; } /********************************************************************** 函数名称:u16 VS_Ram_Test() 函数功能:RAM测试 入口参数:无 返回参数:u16 RAM测试结果,VS1003若得到0x807F,则表明完好,VS1053则为0X83FF 解读作者:Aaron ***********************************************************************/ u16 VS_Ram_Test(void) { VS_HD_Reset(); /* 硬件复位 */ VS_WR_Cmd(SPI_MODE,0x0820); /* 进入VS10XX的测试模式 */ while (VS_DQ==0); /* 等待DREQ为高 */ VS_SPI_SpeedLow(); /* 低速 */ VS_XDCS=0; /* xDCS = 1,选择VS10XX的数据接口 */ VS_SPI_ReadWriteByte(0x4d); VS_SPI_ReadWriteByte(0xea); VS_SPI_ReadWriteByte(0x6d); VS_SPI_ReadWriteByte(0x54); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); VS_SPI_ReadWriteByte(0x00); delay_ms(150); VS_XDCS=1; return VS_RD_Reg(SPI_HDAT0); /* VS1003如果得到的值为0x807F,则表明完好;VS1053为0X83FF */ }5.2 main.c主函数代码解读 /************************************************ 函数名称:int main() 函数功能:主函数 入口参数:无 返回参数:int 解读作者:Aaron *************************************************/ int main(void) { delay_init(); NVIC_Configuration(); LED_Init(); KEY_Init(); My_USART1_Init(); VS_Init(); /* 包含对SPI1初始化 */ printf("存储器测试:%d\r\n",VS_Ram_Test()); while(1) { DS0=0; printf("开始播放单频信号\r\n"); VS_Sine_Test(); delay_ms(1000); DS0=1; delay_ms(1000); } }实验结果 接上耳机,能听到200ms的3000Hz单频声,然后紧接着听到400ms的750Hz单频声。 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |